using Acme.BookStore.Car;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp;
using System.Threading.Tasks;
using System.Linq;
using System.Collections.Generic;

namespace Acme.BookStore.Car
{
    public class OutStockOrderAppService : CrudAppService<
        OrderOutStock, OutStockOrderDto, int, PagedAndSortedResultRequestDto, CreateUpdateOutStockOrderDto>, IOutStockOrderAppService
    {
        private readonly IRepository<InventryTran, int> _inventoryTransferRepository;
        private readonly IRepository<Merchandise, int> _merchandiseRepository;
        private readonly IRepository<OrderOutDetail, int> _outStockOrderDetailRepository;

        public OutStockOrderAppService(
            IRepository<OrderOutStock, int> repository,
            IRepository<InventryTran, int> inventoryTransferRepository,
            IRepository<Merchandise, int> merchandiseRepository,
            IRepository<OrderOutDetail, int> outStockOrderDetailRepository
        ) : base(repository)
        {
            _inventoryTransferRepository = inventoryTransferRepository;
            _merchandiseRepository = merchandiseRepository;
            _outStockOrderDetailRepository = outStockOrderDetailRepository;
        }

        public async Task<OutStockOrderDtoWithDetails> CreateWithDetailsAsync(CreateUpdateOutStockOrderDto input)
        {
            // 1. 添加主表
            var outStockOrder = ObjectMapper.Map<CreateUpdateOutStockOrderDto, OrderOutStock>(input);
            // 新增：生成出库单号
            outStockOrder.OrderNo = "CK" + System.DateTime.Now.ToString("yyyyMMddHHmmssfff");
            outStockOrder = await Repository.InsertAsync(outStockOrder, autoSave: true);

            if (input.Details != null && input.Details.Count > 0)
            {
                foreach (var detailDto in input.Details)
                 {
                var detail = ObjectMapper.Map<CreateUpdateOutStockOrderDetailDto, OrderOutDetail>(detailDto);
                detail.OutOrderId = outStockOrder.Id;
                await _outStockOrderDetailRepository.InsertAsync(detail);
                }
            }

            // 3. 返回主表和子表
            var outStockOrderDto = ObjectMapper.Map<OrderOutStock, OutStockOrderDto>(outStockOrder);
            var detailDtos = input.Details?.Select(d => ObjectMapper.Map<CreateUpdateOutStockOrderDetailDto, OutStockOrderDetailDto>(d)).ToList();

            return new OutStockOrderDtoWithDetails
            {
                OutStockOrder = outStockOrderDto,
                Details = detailDtos
            };
        }

        /// <summary>
        /// 根据调拨单生成出库单及明细（不直接保存，返回前端编辑）
        /// </summary>
        public async Task<OutStockOrderDtoWithDetails> CreateFromInventoryTransferAsync(int inventoryTransferId)
        {
            // 1. 查询调拨单主表
            var transfer = await _inventoryTransferRepository.GetAsync(inventoryTransferId);
            if (transfer == null)
                throw new UserFriendlyException("调拨单不存在");

            // 2. 查询调拨明细
            var transferDetails = await _merchandiseRepository.GetListAsync(x => x.InventoryTranId == inventoryTransferId);

            // 3. 组装出库单主表
            var outStockOrder = new OutStockOrderDto
            {
                Id = transfer.Id, // 联查：用调拨单id
                InventoryTranId = transfer.Id,
                InventoryTransferType = transfer.InventoryTransferType,
                InventoryTransferNo = transfer.InventoryTransferNo,
                InventoryTransferOUT = transfer.InventoryTransferOUT,
                OutDateTime = System.DateTime.Now,
                InventoryTransferOperator = transfer.InventoryTransferOperator,
                Remarks = transfer.Remarks,
                OrderNo = "CK" + System.DateTime.Now.ToString("yyyyMMddHHmmssfff") // 新增：生成出库单号
            };

            // 4. 组装出库单明细
            var outStockOrderDetails = transferDetails.Select(d => new OutStockOrderDetailDto
            {
                Id = d.Id, // 联查：用调拨明细id
                OutOrderId = null, // 新建时无主表Id
                MerchandiseId = d.GoodsId,
                MerchandiseNo = d.MerchandiseNo,
                MerchandiseName = d.MerchandiseName,
                MerchandiseType = d.MerchandiseType,
                MerchandiseModel = d.MerchandiseModel,
                MerchandiseUnit = d.MerchandiseUnit,
                MerchandiseOut = d.MerchandiseOut,
                OutKuwei = null, // 由前端填写
                MerchandiseNumber = d.MerchandiseNumber,
                OutOrderNumber = null, // 由前端填写
                MerchandiseINPrice = d.MerchandiseINPrice,
                OutOrderPrice = null, // 由前端填写
                Reamres = d.Reamres
            }).ToList();

            return new OutStockOrderDtoWithDetails
            {
                OutStockOrder = outStockOrder,
                Details = outStockOrderDetails
            };
        }

        /// <summary>
        /// 根据出库单ID联查主表和明细
        /// </summary>
        public async Task<OutStockOrderDtoWithDetails> GetWithDetailsAsync(int outStockOrderId)
        {
            // 1. 查主表
            var outStockOrder = await Repository.GetAsync(outStockOrderId);
            // 2. 查子表
            var details = await _outStockOrderDetailRepository.GetListAsync(d => d.OutOrderId == outStockOrderId);
            // 3. 映射DTO
            var outStockOrderDto = ObjectMapper.Map<OrderOutStock, OutStockOrderDto>(outStockOrder);
            var detailDtos = details.Select(d => ObjectMapper.Map<OrderOutDetail, OutStockOrderDetailDto>(d)).ToList();
            // 4. 返回
            return new OutStockOrderDtoWithDetails
            {
                OutStockOrder = outStockOrderDto,
                Details = detailDtos
            };
        }

        /// <summary>
        /// 根据InventoryTranId查询所有出库单及其明细（主表+子表）
        /// </summary>
        public async Task<List<OutStockOrderDtoWithDetails>> GetAllWithDetailsByInventoryTranIdAsync(int inventoryTranId)
        {
            // 1. 查所有主表（根据InventoryTranId过滤）
            var outStockOrders = await Repository.GetListAsync(x => x.InventoryTranId == inventoryTranId);
            // 2. 查所有明细（只查属于这些主表的明细）
            var outOrderIds = outStockOrders.Select(o => o.Id).ToList();
            var allDetails = await _outStockOrderDetailRepository.GetListAsync(d => outOrderIds.Contains(d.OutOrderId ?? 0));
            // 3. 按主表分组
            var result = outStockOrders.Select(order =>
            {
                var dto = ObjectMapper.Map<OrderOutStock, OutStockOrderDto>(order);
                var details = allDetails
                    .Where(d => d.OutOrderId == order.Id)
                    .Select(d => ObjectMapper.Map<OrderOutDetail, OutStockOrderDetailDto>(d))
                    .ToList();
                return new OutStockOrderDtoWithDetails
                {
                    OutStockOrder = dto,
                    Details = details
                };
            }).ToList();
            return result;
        }
    }
} 